鐵人賽前面的90%,提到了許多與品質相關的工具、作法、設計理念以及品質指標。但系統還有一個很重要的指標:效能。
效能指標,算不算是品質指標之一?那就要看怎麼去定義品質指標了。效能對系統來說相當重要,但通常是一個相對值,而很多時候為了達到效能的可接受值,我們得犧牲其他的品質指標,例如安全性(通常最不會犧牲的指標)、可擴充性、可維護性等等,用最小的力氣取得可接受的效能調校,是系統開發中一項很重要的概念。
這篇文章不會提到太多艱深的效能調校issue,因為每一類的效能調校可能都可以開一門一學期的課,這邊只用最簡單的方式,來說明怎麼樣來進行效能相關的檢視。
[如何提升系統品質]系列文章連結
在MSDN上,patterns and practices Developer Center分享了一份很完整的performance與scalability的guidance:Improving .NET Application Performance and Scalability,下面的圖片均來自這份guidance。
整個Engineering for performance可以區分成幾個層面來進行,請見下圖:
包括了以下幾項,
1.Performance objectives:
訂出目標,針對目標來進行效能調校。可以知道什麼時候已經達成了目標,而不必一直投入額外成本,為了不必要的需求調校效能。
目標可能包括了:
(1)Response Time(回應時間,server對一個request到做出回應的時間)
(2)Throughput(每一個單位時間,server所能處理的request數或一秒內可以處理的交易量)
(3)Resource utilization(資源的使用,CPU、Memory、disk I/O、network I/O)
(4)Workload(負載量,系統要能承受多少線上使用者同時動作,最大的資料量、交易量等等...)
建議畫出一個矩陣圖表來衡量。
在設定目標的同時,請把『資源』放在心裡,每一個目標都會跟資源息息相關。包括了網路資源(頻寬)、硬體資源等等...
2.Performance modeling:
透過建立一個Performance model,可在系統開發的過程中,提供一個條理清楚、可重複檢視是否達到目標、是否有所遺漏的自我review與設計方向。
好處:
(1)讓performance不再是等到系統開發完畢,才回頭調整的任務。而是在開發中就可以依據這個model隨時調整與檢視。
(2)在系統發展過程,根據訂出的數據標準,來評估tradeoff,以及是否及早調整架構。
(3)測試案例的輔助,可以在每個階段重複的讓開發團隊檢視,是否偏離目標。(有點像Scrum的burndown chart)
Performance model裡面,可能需要包括下面幾項:
3.Architecture and design guidelines
提供了一些原則,在架構與系統設計的時候可以拿來遵循或code review時檢視。
4.A performance and scalability frame
簡單的說,就是把對Performance跟Scalability相關的issues列出來做個memo。
例如:高內聚低耦合、layer/tier溝通方式、平行處理、資源管理、快取管理、狀態管理、資料結構/演算法 等等...
5.Measuring, Testing, and Tuning
列出要測量的目標、數字,以哪幾種Testing的方式進行,並針對哪一些面向來進行調校。
(1)測量目標數字,就如同上面的performance objectives,定義這個系統針對這些目標的門檻值。
(2)Testing可能包括了Load Testing(從平均loading到尖峰,直到通過定義的門檻值,藉此找出效能瓶頸在哪), Stress Testing(正常的環境下,持續增加loading,藉此找出系統中,因為high loading才會產生的bug。例如同步問題、Race conditions、Memory leaks或網路封包遺失等等...)與Capacity Testing(輔助Load Testing,可藉此定義出Scaling策略,是要Scale up還是Scale out)。
6.Roles and life cycle
定義出與performance and scalability 相關的角色,以及在每個階段他們的職責。
上述的要點,整理成一張framework的圖示,就會像這樣:
簡化版的策略
上面那一整套等於是內功,需要好好消化、思考、設計才能完整的體會與導入。
這邊則提出另一種簡單、白話,不需要太多內功也可以做的事。
步驟:
1.效能問題種類區分:
把效能的問題,以3-layer的方式來區分,定義performance的問題,來自於UI層、BL層還是DA層。
(1)UI可能包括了網路頻寬、頁面size、以及過多不必要的冗餘動作等等。
(2)BL則可能包括:商業邏輯演算法是否有調校空間、是否能讓佔用資源的時間縮短等等。
(3)DA層就是直接定義為DB執行的動作,是否要建立index、減少SQL查詢執行時間、轉換成stored procedure、及早準備好要查詢的資料等等...
[註]快取、序列化等等的動作,就像上一篇文章AOP提到的垂直層,是每一層出問題時都要檢視與思考的。
2.找出效能瓶頸:
(1)UI層(以網頁為例):
透過工具來幫忙檢測與評分,例如YSlow(Yahoo), PageSpeed(Google)
(2)BL層:
可透過上面文章中所提的Load Testing, Performance Testing等等測試方式,或是在開發階段時,使用AOP的方式來記錄每一個方法的執行時間,再透過整合測試或自動測試等,對重要的scenario進行performance監控。
(3)DA層:
DB則可透過DB profile以及相關的指令,瞭解哪一些動作是最耗時間與資源的。(可以參考其他鐵人寫的系列文:SQL SERVER 2008效能監控與最佳化)
3.針對效能瓶頸進行調校:
就跟打蛇打七吋一樣,抓到效能瓶頸後,針對該點調校,可能讓效能有幾倍、幾十倍甚至幾百倍的提升。
結論
效能調校還是一門超大的學問,簡單的歸納下面幾個重點:
(1)找到對的效能偵測工具與方式
(2)建立出對的開發工法與performance modeling
(3)及早在系統開發期間進行檢視
(4)針對瓶頸來進行調校
希望大家的系統都可以活得很順利。